package cn.easyutil.easyproject.easySpringboot.handler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import cn.easyutil.easyproject.easySpringboot.context.Context;
import cn.easyutil.easyproject.easySpringboot.util.RequestPool;
import com.example.easyJavaUtil.JsonUtil;
import com.example.easyJavaUtil.LoggerUtil;
import com.example.easyJavaUtil.StringUtil;

public class ServletRequestWrapper extends HttpServletRequestWrapper {
	 
    private Map<String , String[]> params = new HashMap<String, String[]>();
    
    public ServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.params.putAll(request.getParameterMap());
    }
 
    /**
     * 重载一个构造方法
     * @param request
     * @param extendParams
     */
    public ServletRequestWrapper(HttpServletRequest request , Map<String , String[]> extendParams) throws IOException {
        this(request);
        addAllParameters(extendParams);
    }
 
    @Override
    public String getParameter(String name) {
        String[]values = params.get(name);
        if(values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }
 
    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }
 
    public void addAllParameters(Map<String , String[]>otherParams) {
        for(Map.Entry<String , String[]>entry : otherParams.entrySet()) {
            addParameter(entry.getKey() , entry.getValue());
        }
    }
 
 
    public void addParameter(String name , Object value) {
        if(value != null) {
            if(value instanceof String[]) {
                params.put(name , (String[])value);
            }else if(value instanceof String) {
                params.put(name , new String[] {(String)value});
            }else {
                params.put(name , new String[] {String.valueOf(value)});
            }
        }
    }
    
    /**
     * 此处需要修改请求参数列表，如果经过AES加密，只会有一个参数
     * 实际controller层赋值的时候，需要将AES的参数解密，并且动态增加参数key和val
     * @return
     */
    @Override
    public Enumeration<String> getParameterNames() {
        Enumeration<String> enumeration = super.getParameterNames();
        ArrayList<String> list = Collections.list(enumeration);
        list.addAll(params.keySet());
        //是否有加密字段
        Map<String, Object> map = decrypt("body", ServletRequestAuthorition.reqToken.get());
        if(map!=null && !map.isEmpty()){
        	LoggerUtil.info(this.getClass(), RequestPool.getSessionAttribute(Context.threadLocal_request_url)+"解密后的请求参数：" + JsonUtil.beanToJson(map));
        	Set<Entry<String, Object>> entry = map.entrySet();
        	for (Entry<String, Object> en : entry) {
				list.add(en.getKey());
				addParameter(en.getKey(), en.getValue());
			}
        	return Collections.enumeration(list);
        }
        return super.getParameterNames();
//        if (list.contains(RequestPool.getAESParamKeyName())){
//        	String parameter = getParameter(RequestPool.getAESParamKeyName());
//        	//进行解密
//        	parameter = StringUtil.AESDecode(parameter, RequestPool.getToken());
//        	LoggerUtil.info(this.getClass(), RequestPool.getSessionAttribute(Context.threadLocal_request_url)+"解密后的请求参数：" + parameter);
//        	Map<String, Object> map = RequestPool.synchronizeParam(parameter);
//        	
//            return Collections.enumeration(list);
//        }else {
//            return super.getParameterNames();
//        }
    }
    
    /**
     * 解密(如果修改解密规则，需要重写此方法)
     * @param parameterName	request中被加密的数据的key
     * @param token	解密使用的token
     * @return
     */
    public Map<String, Object> decrypt(String parameterName,String token){
    	if(StringUtil.isEmpty(parameterName) || StringUtil.isEmpty(token)){
    		return null;
    	}
    	String parameter = getParameter(parameterName);
    	if(StringUtil.isEmpty(parameter)){
    		return null;
    	}
    	//进行解密
    	parameter = StringUtil.AESDecode(parameter, token);
    	if(StringUtil.isEmpty(parameter) || !JsonUtil.isJson(parameter)){
    		return null;
    	}
    	return synchronizeParam(parameter);
    }
    
    /**
     * 将用户请求的数据同步到request
     * @param json
     */
    @SuppressWarnings("unchecked")
	private Map<String, Object> synchronizeParam(String json){
    	//最终要放回request的参数
    	Map<String, Object> param = new HashMap<String, Object>();
    	//用户请求的json参数
    	Map<String, Object> map = JsonUtil.jsonToMap(json);
    	Set<Entry<String, Object>> set = map.entrySet();
    	for (Entry<String, Object> entry : set) {
			String key = entry.getKey();
			Object value = entry.getValue();
			if(value instanceof Map){
				Map<String, Object> mapValue = (Map<String, Object>) value;
				putMapParam(mapValue,key,param);
				continue;
			}
			param.put(key, value.toString());
		}
    	return param;
    }
    
    /**
     * 添加map参数到request
     * @param mapValue
     * @param key
     * @param param
     */
    @SuppressWarnings("unchecked")
	private void putMapParam(Map<String, Object> mapValue, String key, Map<String, Object> param){
    	Set<Entry<String, Object>> set = mapValue.entrySet();
    	for (Entry<String, Object> entry : set){
    		String key2 = entry.getKey();
    		Object value = entry.getValue();
    		if(value instanceof Map){
    			Map<String, Object> map = (Map<String, Object>) value;
				putMapParam(map, key+"."+key2, param);
			}else{
				param.put(key+"."+key2, value);
			}
    	}
    }
}
